from django.contrib.auth.models import Group
from django.db.models.signals import post_save, m2m_changed, post_delete

from account.model_serializers import UserSerializer
from account.models import User
from permissions.models import GenericPermissions, Component, Route, Api, FileTag, PermissionUser, PermissionGroup
from utils.mixins.common_mixins.logger import common_logger


def post_save_component(sender, instance, created, **kwargs):
    # 保存或者更新component的权限
    if created:
        gp_visible = GenericPermissions(content_object=instance, name=f'visible_{instance.code}',
                                        code=f'{instance.code}',
                                        status=0, description=f'{instance.name} 显示')
        gp_disabled = GenericPermissions(content_object=instance, name=f'disabled_{instance.code}',
                                         code=f'{instance.code}',
                                         status=1, description=f'{instance.name} 置灰')
        gp_invisible = GenericPermissions(content_object=instance, name=f'invisible_{instance.code}',
                                          code=f'{instance.code}',
                                          status=2, description=f'{instance.name} 隐藏')
        GenericPermissions.objects.bulk_create([gp_visible, gp_disabled, gp_invisible])
    else:
        _visible = instance.generic_permissions.get(cod=f'{instance.code}', status=0)
        _disabled = instance.generic_permissions.get(code=f'{instance.code}', status=1)
        _invisible = instance.generic_permissions.get(code=f'{instance.code}', status=2)

        gp_visible = GenericPermissions(id=_visible.id, name=f'visible_{instance.code}',
                                        description=f'{instance.name} 显示')
        gp_disabled = GenericPermissions(id=_disabled.id, name=f'disabled_{instance.code}',
                                         description=f'{instance.name} 置灰')
        gp_invisible = GenericPermissions(id=_invisible.id, name=f'invisible_{instance.code}',
                                          description=f'{instance.name} 隐藏')
        GenericPermissions.objects.bulk_update([gp_visible, gp_disabled, gp_invisible],
                                               ['name', 'description'])


def post_save_route(sender, instance, created, **kwargs):
    # 保存或者更新route的权限
    if created:
        gp_visible = GenericPermissions(content_object=instance, name=f'visible_{instance.code}',
                                        code=f'{instance.code}',
                                        status=1, description=f'{instance.name} 允许访问')
        gp_invisible = GenericPermissions(content_object=instance, name=f'invisible_{instance.code}',
                                          code=f'{instance.code}',
                                          status=0, description=f'{instance.name} 禁止访问')
        GenericPermissions.objects.bulk_create([gp_visible, gp_invisible])
    else:
        _visible = instance.generic_permissions.get(code=f'{instance.code}', status=1)
        _invisible = instance.generic_permissions.get(code=f'{instance.code}', status=0)

        gp_visible = GenericPermissions(id=_visible.id, name=f'visible_{instance.code}',
                                        description=f'{instance.name} 允许访问')
        gp_invisible = GenericPermissions(id=_invisible.id, name=f'invisible_{instance.code}',
                                          description=f'{instance.name} 禁止访问')
        GenericPermissions.objects.bulk_update([gp_visible, gp_invisible],
                                               ['name', 'description'])


def post_save_api(sender, instance, created, **kwargs):
    # 保存或者更新api的权限
    if created:
        gp_access = GenericPermissions(content_object=instance, name=f'access_{instance.code}', code=f'{instance.code}',
                                       status=1,
                                       description=f'{instance.name} 允许调用')
        gp_forbidden = GenericPermissions(content_object=instance, name=f'forbidden_{instance.code}',
                                          code=f'{instance.code}',
                                          status=0,
                                          description=f'{instance.name} 禁止调用')
        GenericPermissions.objects.bulk_create([gp_access, gp_forbidden])
    else:
        _access = instance.generic_permissions.get(code=f'{instance.code}', status=1)
        _forbidden = instance.generic_permissions.get(code=f'{instance.code}', status=0)

        gp_visible = GenericPermissions(id=_access.id, name=f'access_{instance.code}',
                                        description=f'{instance.name} 允许调用')
        gp_invisible = GenericPermissions(id=_forbidden.id, name=f'forbidden_{instance.code}',
                                          description=f'{instance.name} 禁止调用')
        GenericPermissions.objects.bulk_update([gp_visible, gp_invisible],
                                               ['name', 'description'])


def post_save_file_tag(sender, instance, created, **kwargs):
    if created:
        gp_upload_access = GenericPermissions(content_object=instance, name=f'uploadAccess_{instance.code}',
                                              code=f'upload__{instance.code}', status=1,
                                              description=f'{instance.name} 允许上传')
        gp_upload_forbidden = GenericPermissions(content_object=instance, name=f'uploadForbidden_{instance.code}',
                                                 code=f'upload__{instance.code}', status=0,
                                                 description=f'{instance.name} 禁止上传')
        gp_download_access = GenericPermissions(content_object=instance, name=f'downloadAccess_{instance.code}',
                                                code=f'download__{instance.code}', status=1,
                                                description=f'{instance.name} 允许下载')
        gp_download_forbidden = GenericPermissions(content_object=instance, name=f'downloadForbidden_{instance.code}',
                                                   code=f'download__{instance.code}', status=0,
                                                   description=f'{instance.name} 禁止下载')
        gp_preview_access = GenericPermissions(content_object=instance, name=f'previewAccess_{instance.code}',
                                               code=f'preview__{instance.code}', status=1,
                                               description=f'{instance.name} 允许预览')
        gp_preview_forbidden = GenericPermissions(content_object=instance, name=f'previewForbidden_{instance.code}',
                                                  code=f'preview__{instance.code}', status=0,
                                                  description=f'{instance.name} 禁止预览')
        GenericPermissions.objects.bulk_create(
            [gp_upload_forbidden, gp_upload_access, gp_download_forbidden,
             gp_download_access, gp_preview_forbidden, gp_preview_access]
        )
    else:
        _upload_access = instance.generic_permissions.get(code=f'upload__{instance.code}', status=1)
        _upload_forbidden = instance.generic_permissions.get(code=f'upload__{instance.code}', status=0)
        _download_access = instance.generic_permissions.get(code=f'download__{instance.code}', status=1)
        _download_forbidden = instance.generic_permissions.get(code=f'download__{instance.code}', status=0)
        _preview_access = instance.generic_permissions.get(code=f'preview__{instance.code}', status=1)
        _preview_forbidden = instance.generic_permissions.get(code=f'preview__{instance.code}', status=0)

        gp_upload_access = GenericPermissions(id=_upload_access.id, name=f'uploadAccess_{instance.code}',
                                              description=f'{instance.name} 允许上传')
        gp_upload_forbidden = GenericPermissions(id=_upload_forbidden.id, name=f'uploadForbidden_{instance.code}',
                                                 description=f'{instance.name} 禁止上传')
        gp_download_access = GenericPermissions(id=_download_access.id, name=f'downloadAccess_{instance.code}',
                                                description=f'{instance.name} 允许下载')
        gp_download_forbidden = GenericPermissions(id=_download_forbidden.id, name=f'downloadForbidden_{instance.code}',
                                                   description=f'{instance.name} 禁止下载')
        gp_preview_access = GenericPermissions(id=_preview_access.id, name=f'previewAccess_{instance.code}',
                                               description=f'{instance.name} 允许预览')
        gp_preview_forbidden = GenericPermissions(id=_preview_forbidden.id, name=f'previewForbidden_{instance.code}',
                                                  description=f'{instance.name} 禁止预览')
        GenericPermissions.objects.bulk_update([gp_upload_access, gp_download_access, gp_preview_access,
                                                gp_upload_forbidden, gp_download_forbidden, gp_preview_forbidden],
                                               ['name', 'description'])


def post_save_user(sender, instance, created, **kwargs):
    """
    保存或者更新用户时, 同步更新到v_auth_user表中, 并同步组信息
    """
    if created:
        PermissionUser.objects.create(**UserSerializer(instance).data)
    else:
        PermissionUser.objects.filter(id=instance.id).update(**UserSerializer(instance).data)


def post_delete_user(sender, instance, **kwargs):
    """
    删除用户时, 同步删除v_auth_user表中的数据
    """
    PermissionUser.objects.filter(id=instance.id).delete()


def m2m_change_user(sender, instance, action, reverse, model, pk_set, **kwargs):
    """
    用户组信息变更时, 同步更新到v_auth_group_user表中
    """
    if action == 'post_add':
        for pk in pk_set:
            group = PermissionGroup.objects.get(id=pk)
            group.user.add(instance)
    elif action == 'post_remove':
        for pk in pk_set:
            group = PermissionGroup.objects.get(id=pk)
            group.user.remove(instance)


def post_save_group(sender, instance, created, **kwargs):
    """
    保存或者更新组时, 同步更新到v_auth_group表中
    """
    if created:
        PermissionGroup.objects.create(name=instance.name, id=instance.id)
    else:
        PermissionGroup.objects.filter(id=instance.id).update(name=instance.name)


def post_delete_group(sender, instance, **kwargs):
    """
    删除组时, 同步删除v_auth_group表中的数据
    """
    PermissionGroup.objects.filter(id=instance.id).delete()


def register_signals():
    post_save.connect(post_save_component, sender=Component, dispatch_uid='permissions.signals.post_save_component')
    post_save.connect(post_save_route, sender=Route, dispatch_uid='permissions.signals.post_save_route')
    post_save.connect(post_save_api, sender=Api, dispatch_uid='permissions.signals.post_save_api')
    post_save.connect(post_save_file_tag, sender=FileTag, dispatch_uid='permissions.signals.post_save_file_tag')
    post_save.connect(post_save_user, sender=User, dispatch_uid='permissions.signals.post_save_user')
    post_delete.connect(post_delete_user, sender=User, dispatch_uid='permissions.signals.post_delete_user')
    post_save.connect(post_save_group, sender=Group, dispatch_uid='permissions.signals.post_save_group')
    post_delete.connect(post_delete_group, sender=Group, dispatch_uid='permissions.signals.post_delete_group')
    m2m_changed.connect(m2m_change_user, sender=User.groups.through, dispatch_uid='permissions.signals.m2m_change_user')

    common_logger.info('注册权限信号成功')
